//
//  GTHttpManager.m
//  GTNetWorking
//
//  Created by Mr.Wei on 2021/2/23.
//

#import "GTHttpManager.h"
#import "GTHTTPRequestSerializer.h"
@interface GTHttpManager()<NSURLSessionDelegate>
@property (readwrite, nonatomic, strong) NSURLSessionConfiguration *sessionConfiguration;

@property (nonatomic, strong) GTHTTPRequestSerializer * requestSerializer;

@property (readwrite, nonatomic, strong) NSOperationQueue *operationQueue;

@property (readwrite, nonatomic, strong) NSURLSession *session;

@end
@implementation GTHttpManager

+(instancetype)manager{
    return [[[self class]alloc] initWithBaseURL:nil];
}

- (instancetype)init{
    return [self initWithBaseURL: nil];
}

-(instancetype)initWithBaseURL:(NSURL *)url{
    return [self initWithBaseURL:url sessionConfiguration:nil];;
}
- (instancetype)initWithBaseURL:(NSURL *)url sessionConfiguration:(NSURLSessionConfiguration *)configuration{
    self = [super init];
    if (!self) {
        return nil;
    }
    if (!configuration) {
        configuration = [NSURLSessionConfiguration defaultSessionConfiguration];
    }
    self.sessionConfiguration = configuration;

    self.operationQueue = [[NSOperationQueue alloc] init];
    self.operationQueue.maxConcurrentOperationCount = 1;
    //如果BaseURL不为空的话，确保BaseURL以"/"结尾
    if ([[url path] length] > 0 && ![[url absoluteString] hasSuffix:@"/"]) {
        url = [url URLByAppendingPathComponent:@""];
    }
    
    self.requestSerializer = [GTHTTPRequestSerializer serializer];
    
//    self.responseSerializer = [AFJSONResponseSerializer serializer];
//
//    self.securityPolicy = [AFSecurityPolicy defaultPolicy];

//#if !TARGET_OS_WATCH
//    self.reachabilityManager = [AFNetworkReachabilityManager sharedManager];
//#endif

//    self.mutableTaskDelegatesKeyedByTaskIdentifier = [[NSMutableDictionary alloc] init];
//
//    self.lock = [[NSLock alloc] init];
//    self.lock.name = AFURLSessionManagerLockName;

//    [self.session getTasksWithCompletionHandler:^(NSArray *dataTasks, NSArray *uploadTasks, NSArray *downloadTasks) {
//        for (NSURLSessionDataTask *task in dataTasks) {
//            [self addDelegateForDataTask:task uploadProgress:nil downloadProgress:nil completionHandler:nil];
//        }
//
//        for (NSURLSessionUploadTask *uploadTask in uploadTasks) {
//            [self addDelegateForUploadTask:uploadTask progress:nil completionHandler:nil];
//        }
//
//        for (NSURLSessionDownloadTask *downloadTask in downloadTasks) {
//            [self addDelegateForDownloadTask:downloadTask progress:nil destination:nil completionHandler:nil];
//        }
//    }];

    return self;
}


- (nullable NSURLSessionDataTask *)GET:(NSString *)URLString
                            parameters:(nullable id)parameters
                               headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                               success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                               failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure{
    
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"GET"
                                                        URLString:URLString
                                                       parameters:parameters
                                                          headers:headers
                                                          success:success
                                                          failure:failure];
    
    [dataTask resume];
    
    return dataTask;
}
- (nullable NSURLSessionDataTask *)POST:(NSString *)URLString
                             parameters:(nullable id)parameters
                                headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure{
    NSURLSessionDataTask *dataTask = [self dataTaskWithHTTPMethod:@"POST"
                                                        URLString:URLString
                                                       parameters:parameters
                                                          headers:headers
                                                          success:success
                                                          failure:failure];
    
    [dataTask resume];
    
    return dataTask;
}


- (NSURLSessionDataTask *)dataTaskWithHTTPMethod:(NSString *)method
                                       URLString:(NSString *)URLString
                                      parameters:(nullable id)parameters
                                         headers:(nullable NSDictionary <NSString *, NSString *> *)headers
                                         success:(nullable void (^)(NSURLSessionDataTask *task, id _Nullable responseObject))success
                                         failure:(nullable void (^)(NSURLSessionDataTask * _Nullable task, NSError *error))failure
{
    NSError *serializationError = nil;
    NSMutableURLRequest *request = [self.requestSerializer requestWithMethod:method URLString:[[NSURL URLWithString:URLString relativeToURL:self.baseURL] absoluteString] parameters:parameters error:&serializationError];
    for (NSString *headerField in headers.keyEnumerator) {
        [request setValue:headers[headerField] forHTTPHeaderField:headerField];
    }
    if (serializationError) {
        if (failure) {
            dispatch_async(self.completionQueue ?: dispatch_get_main_queue(), ^{
                failure(nil, serializationError);
            });
        }
        return nil;
    }

    __block NSURLSessionDataTask *dataTask = nil;
    dataTask = [self.session dataTaskWithRequest:request completionHandler:^(NSData * _Nullable data, NSURLResponse * _Nullable response, NSError * _Nullable error) {
        if (error) {
            if (failure) {
                failure(dataTask,error);
            }
        }else{
            if (success) {
                success(dataTask,data);
            }
        }
    }];
    return dataTask;
}
- (NSURLSession *)session {
    
    @synchronized (self) {
        if (!_session) {
            _session = [NSURLSession sessionWithConfiguration:self.sessionConfiguration delegate:self delegateQueue:self.operationQueue];
        }
    }
    return _session;
}


- (void)URLSession:(NSURLSession *)session didReceiveChallenge:(NSURLAuthenticationChallenge *)challenge completionHandler:(void (^)(NSURLSessionAuthChallengeDisposition disposition, NSURLCredential * _Nullable credential))completionHandler{
    
    NSURLProtectionSpace *protectionSpace = challenge.protectionSpace;
    if ([protectionSpace.authenticationMethod isEqualToString:NSURLAuthenticationMethodServerTrust]) {
        SecTrustRef serverTrust = protectionSpace.serverTrust;
        completionHandler(NSURLSessionAuthChallengeUseCredential, [NSURLCredential credentialForTrust:serverTrust]);
    } else {
        completionHandler(NSURLSessionAuthChallengePerformDefaultHandling, nil);
    }
}


@end
